package fpzhan.plane.program.connect;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import fpzhan.plane.program.compose.AloneCodeBlockCompose;
import fpzhan.plane.program.compose.ComposeContent;
import fpzhan.plane.program.constant.ComposeType;
import fpzhan.plane.program.function.ChainCodeBlockFunction;
import fpzhan.plane.program.function.CodeBlockFunction;
import fpzhan.plane.program.manager.JsonKeyManager;
import fpzhan.plane.program.proxy.CodeBlockProxy;
import fpzhan.plane.program.struct.CodeBlockStruct;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;


public class ScopeCodeBlockCompose extends AloneCodeBlockCompose {

    private ChainCodeBlockConnect child;

    public ScopeCodeBlockCompose() {
        this.setComposeType(ComposeType.SCOPE);
    }

//    public ScopeCodeBlockCompose(ComposeContext composeContext) {
//        super(composeContext);
//    }


    public ChainCodeBlockFunction flow(CodeBlockFunction codeBlock) {
        return param -> {
            Set preRun = new HashSet<>(param.keySet());
            codeBlock.apply(param);
            Set afterRun = new HashSet<>(param.keySet());
            afterRun.removeAll(preRun);
            param.remove((String[])afterRun.toArray(new String[]{}));
        };

    }

    @Override
    public CodeBlockFunction compose(List<CodeBlockProxy> proxys, JSONObject proxyJson, CodeBlockStruct struct, JSONObject structJson,
                                     ComposeContent composeContent) throws Exception {
        JSONArray proxyArray = new JSONArray(new ArrayList<>());
        JSONArray structArray = new JSONArray(new ArrayList<>());
        CodeBlockFunction function = child.compose(proxyArray,structArray,composeContent);

        proxyJson.put(JsonKeyManager.getJsonKey().scopeKey , proxyArray);
        if (structArray != null && structArray.size() > 0) structJson.put(JsonKeyManager.getJsonKey().scopeKey, structArray);
        return super.compose(proxys, proxyJson, struct, structJson, composeContent, flow(function));
    }


    protected void setChild(ChainCodeBlockConnect child) {
        this.child = child;
    }
}
